﻿using System;
using System.Collections.Generic;
using DrawableObjects.Actors.Aircrafts;
using Sirian.DrawableObject.Actors;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using DrawableObjects.Actors.Aircrafts.Controller;

namespace Serialization.Script
{
    /// <summary>
    /// A formation that orders aircrafts into a wall of death.
    /// </summary>
    public abstract class WallOfDeath_Formation : Formation
    {
        /// <summary>
        /// Puts aircrafts in place and gives them a path to follow.
        /// </summary>
        /// <param name="aircrafts">The aircrafts to put into the formation.</param>
        /// <param name="basePath">The path to follow.</param>
        /// <param name="visibleArea">The area visible.</param>
        /// <param name="useableArea">The area the formation can be inserted into.</param>
        /// <param name="directionY">The direction into which the aircrafts are moved when they are spawned.</param>
        protected void setFormation(List<Aircraft> aircrafts, Path basePath, Bounding visibleArea, Bounding useableArea, float directionY)
        {
            Debug.Assert(directionY != 0);
            Debug.Assert(visibleArea.upperLeft.X > useableArea.upperLeft.X);
            Debug.Assert(visibleArea.upperLeft.Y > useableArea.upperLeft.Y);
            Debug.Assert(visibleArea.upperLeft.X + visibleArea.width < useableArea.upperLeft.X + useableArea.width);
            Debug.Assert(visibleArea.upperLeft.Y + visibleArea.height < useableArea.upperLeft.Y + useableArea.height);
            float maxRadius = findMaxRadius(aircrafts) * 4;
            float useableHeight = useableArea.height;
            int objectsPerColumn = (int)Math.Floor(useableHeight / maxRadius);
            int columnns = (int)Math.Ceiling((float)aircrafts.Count / (float)objectsPerColumn);
            Vector2 iterationStart = new Vector2(visibleArea.upperLeft.X + visibleArea.width / 2 + (maxRadius + visibleArea.width / 2) * Math.Sign(directionY), visibleArea.upperLeft.Y + maxRadius / 2); ;
            Vector2 currentPoint = iterationStart;

            int rowCounter = 0;
            int columnCounter = 0;
            foreach (Aircraft aircraft in aircrafts)
            {
                Path aircraftPath = basePath.Clone();
                currentPoint = Vector2.Add(iterationStart, new Vector2(maxRadius * rowCounter * Math.Sign(directionY), 0));
                currentPoint = Vector2.Add(currentPoint, new Vector2(0, maxRadius * columnCounter));
                aircraftPath.moveAllPoints(currentPoint);
                AIControlledAircraft_PathGuided controller = new AIControlledAircraft_PathGuided(aircraftPath);
                controller.setAircraft(aircraft);
                aircraft.controller = controller;
                aircraft.setPosition(currentPoint);
                columnCounter++;
                rowCounter = columnCounter == objectsPerColumn ? rowCounter + 1 : rowCounter;
                columnCounter %= objectsPerColumn;
            }
        }
    }
}

